#include <zephyr/kernel.h>
#include <zephyr/drivers/display.h>
#include <lvgl.h>
#include <string.h>

#include "zephyr/logging/log.h"

#define LVGL_STACK_SIZE 4096
#define LVGL_PRIORITY   5
#define SLEEP_TIME_MS   5

LOG_MODULE_REGISTER(lvgl, LOG_LEVEL_INF);

/* Thread entry */
static void lvgl_thread(void *p1, void *p2, void *p3)
{
    LOG_INF("Hello LVGL!");
    uint32_t count = 0;
    char buf[11] = {0};
    const struct device *display;
    lv_obj_t *hello_label, *counter_label, *rect, *circle;
    lv_style_t rect_style, circle_style;
    lv_point_t rect_points[5] = { {0,0}, {120,0}, {120,20}, {0,20}, {0,0} };
    const uint32_t circle_radius = 15;

    lv_init();
    display = DEVICE_DT_GET(DT_CHOSEN(zephyr_display));
    if (!device_is_ready(display)) {
        printk("Error: display not ready\r\n");
        return;
    }

    /* Create widgets */
    hello_label   = lv_label_create(lv_scr_act());
    lv_label_set_text(hello_label, "Hello, World!");
    lv_obj_align(hello_label, LV_ALIGN_TOP_MID, 0, 5);

    counter_label = lv_label_create(lv_scr_act());
    lv_obj_align(counter_label, LV_ALIGN_BOTTOM_MID, 0, 0);

    /* Rectangle style */
    lv_style_init(&rect_style);
    lv_style_set_line_color(&rect_style, lv_color_hex(0x0000FF));
    lv_style_set_line_width(&rect_style, 3);
    rect = lv_line_create(lv_scr_act());
    lv_obj_add_style(rect, &rect_style, 0);
    lv_line_set_points(rect, rect_points, sizeof(rect_points) / sizeof(rect_points[0]));
    lv_obj_align(rect, LV_ALIGN_TOP_MID, 0, 0);

    /* Circle style */
    lv_style_init(&circle_style);
    lv_style_set_radius(&circle_style, circle_radius);
    lv_style_set_bg_opa(&circle_style, LV_OPA_100);
    lv_style_set_bg_color(&circle_style, lv_color_hex(0xFF0000));
    circle = lv_obj_create(lv_scr_act());
    lv_obj_set_size(circle, circle_radius*2, circle_radius*2);
    lv_obj_add_style(circle, &circle_style, 0);
    lv_obj_align(circle, LV_ALIGN_CENTER, 0, 5);

    display_blanking_off(display);

    while (1) {
        count++;
        if ((count % (1000 / SLEEP_TIME_MS)) == 0) {
            snprintf(buf, sizeof(buf), "%u", count / (1000 / SLEEP_TIME_MS));
            lv_label_set_text(counter_label, buf);
        }

        lv_task_handler();
        k_msleep(SLEEP_TIME_MS);
    }
}

/* Define and start the thread at boot */
K_THREAD_DEFINE(lvgl_tid, LVGL_STACK_SIZE,
                lvgl_thread, NULL, NULL, NULL,
                LVGL_PRIORITY, 0, 0);